package pdf;

import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PdfSuper {
    public static void main(String[] args) throws Exception {
        String outputFile = "/work/public/bold/early/src/main/resources/pdf/sample.pdf";
        Map<String, Object> variables = new HashMap<>();

        List<User> userList = new ArrayList<User>();

        User tom = new User("Tom", 19, 1);
        User amy = new User("Amy", 28, 0);
        User leo = new User("Leo", 23, 1);
        userList.add(tom);
        userList.add(amy);
        userList.add(leo);
        variables.put("title", "User List");
        variables.put("userList", userList);
        variables.put("path", "/work/public/bold/early/src/main/resources/1111.png");


        //模板 和 数据 整合
        String htmlStr = HtmlGenerator.generate("pdf/fileTemplate.html", variables);

        OutputStream out = new FileOutputStream(outputFile);

        // html 页面 转 pdf
        PdfGenerator.generate(htmlStr, out);
    }


    @Data
    @AllArgsConstructor
    public static class User {
        private String name;
        private int age;
        private int sex;
    }

    public static class HtmlGenerator {

        /**
         * Generate html string.
         *
         * @param template  the name of freemarker teamlate.
         * @param variables the data of teamlate.
         * @return htmlStr
         * @throws Exception
         */
        public static String generate(String template, Map<String, Object> variables) throws Exception {

            Configuration config = new Configuration();
            File file = new File("/work/public/bold/early/src/main/resources/");
            try {
                config.setDirectoryForTemplateLoading(file);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            Template tp = config.getTemplate(template); //获取具体模板
            StringWriter stringWriter = new StringWriter();
            BufferedWriter writer = new BufferedWriter(stringWriter);
            tp.setEncoding("UTF-8");
            tp.process(variables, writer);
            String htmlStr = stringWriter.toString();
            writer.flush();
            writer.close();
            return htmlStr;
        }
    }

    public static class PdfGenerator {

        /**
         * Output a pdf to the specified outputstream
         *
         * @param htmlStr the htmlstr
         * @param out     the specified outputstream
         * @throws Exception
         */
        public static void generate(String htmlStr, OutputStream out) throws Exception {
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document doc = builder.parse(new ByteArrayInputStream(htmlStr.getBytes()));
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocument(doc, null);
            renderer.layout();
            renderer.createPDF(out);
            out.close();
        }


//        private void generatePdf(String htmlStr, OutputStream out) throws IOException, DocumentException {
//            //final ServletContext servletContext = getServletContext();
//
//            Document document = new Document(PageSize.A4, 30, 30, 30, 30);
//            document.setMargins(30, 30, 30, 30);
//            PdfWriter writer = PdfWriter.getInstance(document, out);
//            document.open();
//
//            // html内容解析
//            HtmlPipelineContext htmlContext = new HtmlPipelineContext(
//                    new CssAppliersImpl(new XMLWorkerFontProvider() {
//                        @Override
//                        public Font getFont(String fontname, String encoding,
//                                            float size, final int style) {
//                            Font font = null;
//                            if (fontname == null) {
//                                //字体
//                                String fontCn = getChineseFont();
//                                BaseFont bf;
//                                try {
//                                    //注意这里有一个,1
//                                    bf = BaseFont.createFont(fontCn+",1",
//                                            BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
//                                    font = new Font(bf, size, style);
//                                } catch (DocumentException e) {
//                                    e.printStackTrace();
//                                } catch (IOException e) {
//                                    e.printStackTrace();
//                                }
//
//                            }
//                            return font;
//                        }
//                    })) {
//                @Override
//                public HtmlPipelineContext clone()
//                        throws CloneNotSupportedException {
//                    HtmlPipelineContext context = super.clone();
//                    try {
//                        ImageProvider imageProvider = this.getImageProvider();
//                        context.setImageProvider(imageProvider);
//                    } catch (NoImageProviderException e) {
//                    }
//                    return context;
//                }
//            };
//
//            // 图片解析
//            htmlContext.setImageProvider(new AbstractImageProvider() {
//
//                // String rootPath = servletContext.getRealPath("/");
//
//                @Override
//                public String getImageRootPath() {
//                    return "";
//                }
//
//                @Override
//                public Image retrieve(String src) {
//                    if (StringUtils.isEmpty(src)) {
//                        return null;
//                    }
//                    try {
//                        // String imageFilePath = new File(rootPath, src).toURI().toString();
//                        Image image = Image.getInstance(src);
//                        image.setAbsolutePosition(400, 400);
//                        if (image != null) {
//                            store(src, image);
//                            return image;
//                        }
//                    } catch (Throwable e) {
//                        e.printStackTrace();
//                    }
//                    return super.retrieve(src);
//                }
//            });
//            htmlContext.setAcceptUnknown(true).autoBookmark(true)
//                    .setTagFactory(Tags.getHtmlTagProcessorFactory());
//
//            // css解析
//            CSSResolver cssResolver = XMLWorkerHelper.getInstance()
//                    .getDefaultCssResolver(true);
//            cssResolver.setFileRetrieve(new FileRetrieve() {
//                @Override
//                public void processFromStream(InputStream in,
//                                              ReadingProcessor processor) throws IOException {
//                    try (InputStreamReader reader = new InputStreamReader(in,
//                            CHARSET_NAME)) {
//                        int i = -1;
//                        while (-1 != (i = reader.read())) {
//                            processor.process(i);
//                        }
//                    } catch (Throwable e) {
//                    }
//                }
//
//                // 解析href
//                @Override
//                public void processFromHref(String href, ReadingProcessor processor)
//                        throws IOException {
//                    // InputStream is = servletContext.getResourceAsStream(href);
//                    URL url = new URL(href);
//                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
//                    conn.setRequestMethod("GET");
//                    conn.setConnectTimeout(5 * 1000);
//                    InputStream is = conn.getInputStream();
//
//                    try (InputStreamReader reader = new InputStreamReader(is,
//                            CHARSET_NAME)) {
//                        int i = -1;
//                        while (-1 != (i = reader.read())) {
//                            processor.process(i);
//                        }
//                    } catch (Throwable e) {
//                        e.printStackTrace();
//                    }
//                }
//            });
//
//            HtmlPipeline htmlPipeline = new HtmlPipeline(htmlContext,
//                    new PdfWriterPipeline(document, writer));
//            Pipeline<?> pipeline = new CssResolverPipeline(cssResolver,
//                    htmlPipeline);
//            XMLWorker worker = null;
//            worker = new XMLWorker(pipeline, true);
//            XMLParser parser = new XMLParser(true, worker,
//                    Charset.forName(CHARSET_NAME));
//            try (InputStream inputStream = new ByteArrayInputStream(
//                    htmlStr.getBytes())) {
//                parser.parse(inputStream, Charset.forName(CHARSET_NAME));
//            }
//            document.close();
//        }

    }

}
